JavaScript 56.7%
TypeScript 42.6%
1import { NextRequest, NextResponse } from "next/server";2import { prisma } from "@/lib/prisma";3import { logActivity } from "@/lib/activity";4import { trashFiles } from "@/lib/trash";56export async function GET(7 request: NextRequest,8 { params }: { params: { id: string } }9) {10 const file = await prisma.file.findUnique({11 where: { id: params.id },12 include: { folder: true, sharedLinks: true, metadata: true, tags: { include: { tag: true } }, _count: { select: { versions: true } } },13 });1415 if (!file) {16 return NextResponse.json({ error: "File not found" }, { status: 404 });17 }1819 return NextResponse.json({ ...file, size: Number(file.size) });20}2122export async function PATCH(23 request: NextRequest,24 { params }: { params: { id: string } }25) {26 const body = await request.json().catch(() => ({}));27 const { name, folderId } = body as { name?: string; folderId?: string | null };2829 const file = await prisma.file.findUnique({ where: { id: params.id } });30 if (!file) {31 return NextResponse.json({ error: "File not found" }, { status: 404 });32 }3334 const updateData: Record<string, unknown> = {};3536 if (name !== undefined) {37 const trimmed = typeof name === "string" ? name.trim() : "";38 if (!trimmed) return NextResponse.json({ error: "Nom requis" }, { status: 400 });39 if (/[\\/]/.test(trimmed)) return NextResponse.json({ error: "Le nom ne peut pas contenir « / » ou « \\ »" }, { status: 400 });40 if (trimmed !== file.name) {41 updateData.name = trimmed;42 await logActivity("RENAME", params.id, `Renamed ${file.name} -> ${trimmed}`);43 }44 }4546 if (folderId !== undefined) {47 const target = folderId === "root" || folderId === null ? null : folderId;48 if (target) {49 const exists = await prisma.folder.findUnique({ where: { id: target }, select: { id: true } });50 if (!exists) return NextResponse.json({ error: "Dossier de destination introuvable" }, { status: 404 });51 }52 if (target !== file.folderId) {53 updateData.folderId = target;54 await logActivity("MOVE", params.id, `Moved ${file.name} to folder ${folderId}`);55 }56 }5758 if (Object.keys(updateData).length === 0) {59 return NextResponse.json({ ...file, size: Number(file.size) });60 }6162 const updated = await prisma.file.update({63 where: { id: params.id },64 data: updateData,65 });6667 return NextResponse.json({ ...updated, size: Number(updated.size) });68}6970/** Mise à la corbeille (restaurable 30 jours) — l'origine est mémorisée pour la restauration. */71export async function DELETE(72 request: NextRequest,73 { params }: { params: { id: string } }74) {75 const file = await prisma.file.findUnique({ where: { id: params.id }, select: { id: true, deletedAt: true } });76 if (!file) {77 return NextResponse.json({ error: "File not found" }, { status: 404 });78 }79 if (file.deletedAt) {80 return NextResponse.json({ success: true, alreadyTrashed: true });81 }8283 await trashFiles([file.id]);8485 return NextResponse.json({ success: true });86}87